# =============================================================================
# 插件名称：重新加载插件
# 作者：詹广权
# 版本：1.0.1
# 版权所有：http://www.cdsjcc.cn/xgj
# 说明：这是一个用于重新加载SketchUp插件的工具，支持激进式清理和重新加载
#       所有Ruby插件文件和扩展，解决SketchUp开发过程中插件更新的问题。
# =============================================================================

module Tzxx
  module ReloadPlugins
    
    # 创建并注册扩展（在扩展管理器中显示）
    unless file_loaded?(__FILE__)
      # 创建扩展对象
      extension = SketchupExtension.new("重新加载插件", "cqqqq.rb")
      extension.description = "这是一个用于重新加载SketchUp插件的工具，支持激进式清理和重新加载所有Ruby插件文件和扩展，解决SketchUp开发过程中插件更新的问题。"
      extension.version = "1.0.1"
      extension.creator = "詹广权"
      extension.copyright = "版权所有：http://www.cdsjcc.cn/xgj"
      
      # 注册扩展到SketchUp扩展管理器
      Sketchup.register_extension(extension, true)
      
      # 添加菜单项
      menu = UI.menu("Plugins")
      menu.add_item("重新加载插件") { self.auto_restart_sketchup }
      
      file_loaded(__FILE__)
    end

    # 带反馈的重新加载方法
    def self.reload_with_feedback
      UI.messagebox("开始刷新所有扩展...")
      result = reload_all_plugins
      if result
        message = "扩展刷新完成！\n\n"
        message += "成功: #{result[:file_success]} 个文件, #{result[:ext_success]} 个扩展\n"
        message += "失败: #{result[:file_fail]} 个文件, #{result[:ext_fail]} 个扩展"
        UI.messagebox(message)
      end
    end

    # 重新加载所有插件的方法（激进版 - 解决 SketchUp 加载限制）
    def self.reload_all_plugins
      model = Sketchup.active_model
      model.start_operation("重新加载所有插件", true)
      
      # 清理Ruby控制台显示（使用安全的方法）
      begin
        # SketchUp没有官方的控制台清理API，使用输出换行的方式
        puts "\n" * 50  # 输出50个换行符来清理显示
        puts "=" * 60
        puts "控制台显示已清理"
      rescue => e
        puts "清理控制台显示时出错: #{e.message}"
      end
      
      puts "=" * 60
      puts "激进重新加载开始于 #{Time.now.strftime('%Y-%m-%d %H:%M:%S')}"
      puts "=" * 60
      
      begin
        start_time = Time.now
        reload_count = 0
        error_count = 0
        extension_reload_count = 0
        extension_error_count = 0
        error_messages = []
        
        # 获取插件目录
        plugins_dir = Sketchup.find_support_file("Plugins")
        unless plugins_dir
          UI.messagebox("找不到插件目录")
          return nil
        end
        
        # 收集所有需要重新加载的Ruby文件
        ruby_files = Dir.glob(File.join(plugins_dir, "**/*.rb"))
        current_file = __FILE__.dup.encode('UTF-8')
        ruby_files.reject! { |file| file.encode('UTF-8') == current_file }
        
        puts "找到 #{ruby_files.length} 个Ruby文件需要重新加载"
        
        # 1. 激进清理：完全重置 Ruby 环境
        puts "\n=== 第1步：激进清理 Ruby 环境 ==="
        aggressive_cleanup
        
        # 2. 清理所有工具栏和观察者
        puts "\n=== 第2步：清理 UI 元素 ==="
        cleanup_ui_elements
        
        # 3. 强制清理所有插件相关的全局状态
        puts "\n=== 第3步：清理全局状态 ==="
        cleanup_global_state
        
        # 4. 重新加载Ruby文件（使用强制策略）
        puts "\n=== 第4步：重新加载文件 ==="
        ruby_files.each_with_index do |file, index|
          begin
            file_basename = File.basename(file, ".rb")
            puts "[#{index + 1}/#{ruby_files.length}] 处理文件: #{File.basename(file)}"
            
            # 激进卸载模块
            aggressive_unload_module(file_basename, file)
            
            # 强制重新加载文件（绕过所有缓存）
            force_reload_file(file)
            reload_count += 1
            puts "  ✓ 强制加载成功"
            
          rescue => e
            error_count += 1
            error_msg = "#{File.basename(file)}: #{e.message}"
            error_messages << error_msg
            puts "  ✗ 加载失败: #{e.message}"
            puts "    #{e.backtrace.first}" if e.backtrace
          end
        end
        
        # 5. 重新加载扩展
        puts "\n=== 第5步：重新加载扩展 ==="
        extension_reload_count, extension_error_count, ext_errors = reload_extensions
        error_messages.concat(ext_errors)
        
        # 6. 最终清理和验证
        puts "\n=== 第6步：最终清理 ==="
        GC.start
        sleep 0.5  # 给系统一点时间处理
        
        # 计算耗时
        elapsed_time = (Time.now - start_time).round(2)
        
        # 显示结果摘要
        puts "\n" + "=" * 60
        puts "激进重新加载完成！耗时: #{elapsed_time} 秒"
        puts "文件: #{reload_count} 成功, #{error_count} 失败"
        puts "扩展: #{extension_reload_count} 成功, #{extension_error_count} 失败"
        puts "=" * 60
        
        if error_count > 0 || extension_error_count > 0
          puts "\n错误详情:"
          error_messages.each { |msg| puts "  - #{msg}" }
        end
        
        puts "\n提示：如果某些插件仍未更新，可能需要重启 SketchUp。"
        puts "这是 SketchUp Ruby 环境的限制，某些深层状态无法在运行时清理。"
        
        model.commit_operation
        
        return {
          file_success: reload_count,
          file_fail: error_count,
          ext_success: extension_reload_count,
          ext_fail: extension_error_count
        }
        
      rescue => e
        puts "重新加载过程出错: #{e.message}"
        puts e.backtrace.join("\n  ")
        model.abort_operation
        UI.messagebox("重新加载插件失败: #{e.message}")
        return nil
      end
    end
    
    # 激进清理 Ruby 环境
    def self.aggressive_cleanup
      puts "激进清理 Ruby 环境..."
      
      # 清理所有非系统常量
      begin
        # 保护重要的系统常量，避免移除
        protected_constants = [
          # SketchUp 相关
          'Sketchup', 'UI', 'Geom', 'Length', 'RUBY', 'ARGV',
          # Ruby 核心类和模块
          'Object', 'Module', 'Class', 'BasicObject', 'Kernel',
          'String', 'Integer', 'Float', 'Array', 'Hash', 'Symbol', 
          'TrueClass', 'FalseClass', 'NilClass', 'Numeric', 'Comparable', 'Enumerable',
          # Ruby 系统模块
          'GC', 'ObjectSpace', 'Process', 'Signal', 'Math', 'Marshal',
          'FileTest', 'File', 'Dir', 'IO', 'STDIN', 'STDOUT', 'STDERR',
          'Time', 'Date', 'DateTime', 'Rational', 'Complex',
          'Thread', 'ThreadGroup', 'Mutex', 'ConditionVariable',
          'Regexp', 'MatchData', 'Encoding', 'Enumerator',
          'Random', 'Range', 'Proc', 'Method', 'UnboundMethod',
          'Binding', 'TracePoint', 'RubyVM', 'Warning',
          # Ruby 标准库核心
          'JSON', 'Base64', 'FileUtils', 'Etc', 'RbConfig'
        ]
        
        Object.constants.each do |const_name|
          const_str = const_name.to_s
          
          # 跳过受保护的常量
          next if protected_constants.any? { |protected| const_str.start_with?(protected) }
          next if protected_constants.include?(const_str)
          
          begin
            const_obj = Object.const_get(const_name)
            # 只清理用户定义的模块和类
            if const_obj.is_a?(Module) && const_obj.respond_to?(:name) && const_obj.name
              # 额外检查：不清理看起来像系统模块的常量
              unless const_str =~ /^(Errno|Warning|Monitor|Fiber|Coverage|Profiler|Debug|Test|MiniTest|RSpec|Benchmark|Logger|OpenSSL|Digest|Zlib|StringIO|Tempfile|Pathname|URI|Net|WEBrick|CGI|ERB|YAML|CSV|RSS|REXML|Psych|Fiddle|DL|Win32|Socket|IPSocket|TCPSocket|UDPSocket|UNIXSocket|BasicSocket|Addrinfo)/
                Object.send(:remove_const, const_name)
                puts "  移除常量: #{const_name}"
              end
            end
          rescue => e
            puts "  清理常量 #{const_name} 失败: #{e.message}"
          end
        end
      rescue => e
        puts "  激进清理常量时出错: #{e.message}"
      end
      
      # 清理全局变量（保留系统变量）
      begin
        global_variables.each do |var|
          next if var.to_s =~ /^\$(LOAD_PATH|LOADED_FEATURES|PROGRAM_NAME|0|\$|\?|!|@|_|~|=|\+|`|'|"|&|\*|<|>|;|,|\.|\/)$/
          next if var.to_s.start_with?('$KCODE', '$SAFE', '$VERBOSE', '$DEBUG')
          
          begin
            eval("#{var} = nil")
            puts "  清理全局变量: #{var}"
          rescue => e
            puts "  清理全局变量 #{var} 失败: #{e.message}"
          end
        end
      rescue => e
        puts "  激进清理全局变量时出错: #{e.message}"
      end
    end
    
    # 清理全局状态
    def self.cleanup_global_state
      puts "清理全局状态..."
      
      # 清理所有 $LOADED_FEATURES 中的插件文件
      begin
        plugins_dir = Sketchup.find_support_file("Plugins")
        removed_count = 0
        
        $LOADED_FEATURES.delete_if do |feature|
          should_remove = feature.include?(plugins_dir) && feature.end_with?('.rb')
          if should_remove
            removed_count += 1
            puts "  移除加载记录: #{File.basename(feature)}"
          end
          should_remove
        end
        
        puts "  总共移除了 #{removed_count} 个加载记录"
      rescue => e
        puts "  清理加载记录时出错: #{e.message}"
      end
      
      # 强制垃圾回收
      3.times do
        GC.start
        sleep 0.1
      end
    end
    
    # 激进卸载模块
    def self.aggressive_unload_module(file_basename, file_path)
      puts "    激进卸载: #{file_basename}"
      
      # 1. 生成所有可能的模块名
      possible_names = generate_possible_module_names(file_basename)
      
      # 2. 在所有可能的命名空间中查找并移除
      [Object, Kernel].each do |namespace|
        possible_names.each do |name|
          if namespace.const_defined?(name)
            begin
              mod = namespace.const_get(name)
              
              # 尝试调用清理方法
              [:cleanup, :unload, :reset, :clear].each do |method|
                if mod.respond_to?(method)
                  mod.send(method)
                  puts "      调用 #{name}.#{method}"
                end
              end
              
              # 移除常量
              namespace.send(:remove_const, name)
              puts "      移除常量: #{namespace.name}::#{name}"
            rescue => e
              puts "      移除 #{name} 失败: #{e.message}"
            end
          end
        end
      end
      
      # 3. 清理相关的全局变量
      global_variables.each do |var|
        if var.to_s.downcase.include?(file_basename.downcase)
          begin
            eval("#{var} = nil")
            puts "      清理相关全局变量: #{var}"
          rescue
            # 忽略无法清理的变量
          end
        end
      end
    end
    
    # 强制重新加载文件（绕过所有缓存）
    def self.force_reload_file(file_path)
      # 1. 确保文件不在 $LOADED_FEATURES 中
      $LOADED_FEATURES.delete_if { |f| f.include?(File.basename(file_path, '.rb')) }
      
      # 2. 读取文件内容并动态执行（绕过 load 缓存）
      begin
        file_content = File.read(file_path, encoding: 'UTF-8')
        
        # 3. 在新的绑定中执行代码
        eval(file_content, binding, file_path)
        
        puts "      强制执行成功"
      rescue => e
        # 如果动态执行失败，回退到普通 load
        puts "      动态执行失败，回退到 load: #{e.message}"
        load file_path
      end
    end
    
    # 清理UI元素
    def self.cleanup_ui_elements
      puts "清理UI元素..."
      
      # 清理工具栏
      begin
        UI.toolbar_names.each do |toolbar_name|
          next if ['Camera', 'Drawing', 'Edit', 'Face Style', 'Large Tool Set', 
                   'Layers', 'Measurements', 'Principal', 'Sections', 'Shadows', 
                   'Standard', 'Views', 'Walk Through'].include?(toolbar_name)
          
          toolbar = UI.toolbar(toolbar_name)
          toolbar.hide if toolbar && toolbar.visible?
        end
      rescue => e
        puts "  清理工具栏时出错: #{e.message}"
      end
      
      # 清理观察者
      begin
        model = Sketchup.active_model
        app = Sketchup
        
        # 清理各种类型的观察者（使用正确的API方法）
        observer_collections = [
          { object: Sketchup, method: :remove_observer, name: "应用观察者" },
          { object: model, method: :remove_observer, name: "模型观察者" },
          { object: model.entities, method: :remove_observer, name: "实体观察者" },
          { object: model.selection, method: :remove_observer, name: "选择观察者" },
          { object: model.materials, method: :remove_observer, name: "材质观察者" }
        ]
        
        # 添加图层观察者（SketchUp 2020+使用tags，之前版本使用layers）
        if model.respond_to?(:tags)
          observer_collections << { object: model.tags, method: :remove_observer, name: "标签观察者" }
        elsif model.respond_to?(:layers)
          observer_collections << { object: model.layers, method: :remove_observer, name: "图层观察者" }
        end
        
        observer_collections.each do |collection_info|
          begin
            obj = collection_info[:object]
            method = collection_info[:method]
            name = collection_info[:name]
            
            # 获取当前观察者列表（如果支持的话）
            observers_method = case obj
            when Sketchup
              :app_observers
            else
              "#{obj.class.name.split('::').last.downcase}_observers".to_sym
            end
            
            if obj.respond_to?(observers_method)
              observers = obj.send(observers_method)
              observers_to_remove = []
              
              observers.each do |observer|
                # 跳过系统观察者
                next if observer.class.name.start_with?('Sketchup::')
                next if observer.class.name.start_with?('UI::')
                observers_to_remove << observer
              end
              
              observers_to_remove.each do |observer|
                obj.send(method, observer)
                puts "  移除#{name}: #{observer.class.name}"
              end
            else
              puts "  #{name}不支持观察者列表获取"
            end
          rescue => e
            puts "  清理#{collection_info[:name]}时出错: #{e.message}"
          end
        end
        
      rescue => e
        puts "  清理观察者时出错: #{e.message}"
      end
    end
    
    # 增强版模块卸载（方案2：不依赖特定代码结构）
    def self.unload_module_enhanced(file_basename, file_path)
      puts "    卸载模块: #{file_basename}"
      
      # 1. 清理 $LOADED_FEATURES 中的记录（关键改进）
      normalized_path = File.expand_path(file_path).gsub('\\', '/')
      removed_features = []
      
      $LOADED_FEATURES.delete_if do |feature|
        feature_path = File.expand_path(feature).gsub('\\', '/') rescue feature
        should_remove = feature_path.include?(file_basename) || 
                       feature_path == normalized_path ||
                       feature.include?(file_basename)
        
        if should_remove
          removed_features << feature
          puts "      移除加载记录: #{File.basename(feature)}"
        end
        should_remove
      end
      
      # 2. 智能检测和清理可能的模块/类常量
      possible_names = generate_possible_module_names(file_basename)
      namespaces_to_check = [Object]
      
      # 动态发现可能的命名空间
      Object.constants.each do |const_name|
        begin
          const_obj = Object.const_get(const_name)
          if const_obj.is_a?(Module) && !const_obj.is_a?(Class)
            namespaces_to_check << const_obj
          end
        rescue
          # 忽略无法访问的常量
        end
      end
      
      # 清理发现的常量
      namespaces_to_check.each do |namespace|
        possible_names.each do |name|
          next unless namespace.const_defined?(name)
          
          begin
            # 尝试调用清理方法
            mod = namespace.const_get(name)
            if mod.respond_to?(:cleanup)
              mod.cleanup
              puts "      调用清理方法: #{namespace.name}::#{name}.cleanup"
            elsif mod.respond_to?(:unload)
              mod.unload
              puts "      调用卸载方法: #{namespace.name}::#{name}.unload"
            end
          rescue => e
            puts "      清理模块方法时出错: #{e.message}"
          end
          
          begin
            namespace.send(:remove_const, name)
            puts "      移除常量: #{namespace.name}::#{name}"
          rescue => e
            puts "      移除常量失败: #{e.message}"
          end
        end
      end
      
      # 3. 清理 file_loaded? 的内部记录
      clear_file_loaded_records(file_path)
      
      # 4. 强制垃圾回收
      GC.start
      
      puts "      清理完成，移除了 #{removed_features.length} 个加载记录"
    end
    
    # 生成可能的模块名称
    def self.generate_possible_module_names(file_basename)
      names = []
      
      # 原始名称
      names << file_basename
      
      # 驼峰命名
      camel_name = camelize(file_basename)
      names << camel_name unless camel_name.empty?
      
      # 大写版本
      names << file_basename.upcase
      
      # 首字母大写版本
      names << file_basename.capitalize
      
      # 添加常见前缀
      names << "Plugin#{camel_name}" unless camel_name.empty?
      names << "#{camel_name}Plugin" unless camel_name.empty?
      
      # 去重并过滤无效名称
      names.uniq.select { |name| name.match(/^[A-Z][A-Za-z0-9_]*$/) }
    end
    
    # 清理 file_loaded? 的内部记录
    def self.clear_file_loaded_records(file_path)
      begin
        # SketchUp 的 file_loaded? 使用内部变量存储已加载文件
        # 我们需要清理这些记录以允许重新执行
        
        # 尝试访问 SketchUp 的内部加载记录（如果可能）
        if defined?(Sketchup) && Sketchup.respond_to?(:file_loaded_clear)
          Sketchup.file_loaded_clear(file_path)
        end
        
        # 清理可能的全局变量记录
        global_vars = global_variables.select { |var| var.to_s.include?('file_loaded') }
        global_vars.each do |var|
          begin
            value = eval(var.to_s)
            if value.is_a?(Array)
              value.delete_if { |item| item.to_s.include?(File.basename(file_path, '.rb')) }
            elsif value.is_a?(Hash)
              value.delete_if { |key, _| key.to_s.include?(File.basename(file_path, '.rb')) }
            end
          rescue
            # 忽略无法处理的全局变量
          end
        end
        
        puts "      清理 file_loaded 记录: #{File.basename(file_path)}"
      rescue => e
        puts "      清理 file_loaded 记录时出错: #{e.message}"
      end
    end
    
    # 重新加载扩展
    def self.reload_extensions
      extension_reload_count = 0
      extension_error_count = 0
      extension_errors = []
      
      # 官方扩展列表（跳过这些）
      official_extensions = [
        '添加位置', 'Add Location', 'Habitat Site Context',
        '动态组件', 'Dynamic Components', 
        '沙盒工具', 'Sandbox Tools'
      ]
      
      Sketchup.extensions.each do |ext|
        begin
          # 跳过官方扩展
          next if official_extensions.any? { |name| ext.name.include?(name) }
          
          puts "处理扩展: #{ext.name} v#{ext.version}"
          
          if ext.loaded?
            puts "  卸载扩展..."
            ext.unload
            
            # 等待卸载完成
            sleep 1.0
            GC.start
            
            # 验证卸载
            if ext.loaded?
              puts "  警告: 扩展未完全卸载"
            end
          end
          
          # 尝试加载
          puts "  重新加载扩展..."
          3.times do |attempt|
            begin
              success = ext.load
              if success && ext.loaded?
                extension_reload_count += 1
                puts "  ✓ 成功加载扩展"
                break
              elsif attempt == 2
                extension_error_count += 1
                error_msg = "扩展 #{ext.name} 加载失败（3次尝试后）"
                extension_errors << error_msg
                puts "  ✗ #{error_msg}"
              else
                puts "  第#{attempt + 1}次尝试失败，重试中..."
                sleep 0.5
              end
            rescue => e
              if attempt == 2
                extension_error_count += 1
                error_msg = "扩展 #{ext.name} 加载出错: #{e.message}"
                extension_errors << error_msg
                puts "  ✗ #{error_msg}"
              else
                puts "  第#{attempt + 1}次尝试出错: #{e.message}，重试中..."
                sleep 0.5
              end
            end
          end
          
        rescue => e
          extension_error_count += 1
          error_msg = "扩展 #{ext.name} 处理出错: #{e.message}"
          extension_errors << error_msg
          puts "  ✗ #{error_msg}"
        end
      end
      
      return extension_reload_count, extension_error_count, extension_errors
    end
    
    # 字符串转驼峰命名
    def self.camelize(str)
      str.split('_').map(&:capitalize).join
    end
    
    # 自动重启SketchUp
    def self.auto_restart_sketchup
      begin
        model = Sketchup.active_model
        current_model_path = model.path
        
        # 直接重新加载，不检查保存状态
        puts "开始重新加载插件，跳过保存检查"
        
        # 使用SketchUp API重新加载
        restart_with_sketchup_api(current_model_path)
        
      rescue => e
        error_msg = "重新加载失败: #{e.message}"
        puts error_msg
        puts e.backtrace.join("\n  ")
        UI.messagebox(error_msg)
      end
    end
    
    # 使用SketchUp API重新加载
    def self.restart_with_sketchup_api(model_path)
      begin
        puts "开始使用SketchUp API重新加载..."
        
        # 显示进度提示到控制台
        puts "正在重新加载插件和模型，请稍候..."
        
        # 1. 重新加载所有插件
        puts "重新加载插件..."
        reload_all_plugins
        
        # 2. 如果有模型路径，重新打开模型
        if !model_path.empty?
          puts "重新打开模型: #{model_path}"
          
          # 创建新模型
          Sketchup.file_new
          
          # 延迟一下确保新模型创建完成
          sleep(0.5)
          
          # 打开指定的模型文件
          if File.exist?(model_path)
            Sketchup.open_file(model_path)
            puts "模型重新加载完成: #{model_path}"
          else
            puts "警告: 模型文件不存在: #{model_path}"
            UI.messagebox("警告: 模型文件不存在，已创建新模型")
          end
        else
          puts "创建新模型"
          Sketchup.file_new
        end
        
        # 3. 强制刷新界面
        Sketchup.active_model.active_view.invalidate
        
        puts "SketchUp API重新加载完成！"
        UI.messagebox("重新加载完成！")
        
      rescue => e
        error_msg = "SketchUp API重新加载失败: #{e.message}"
        puts error_msg
        puts e.backtrace.join("\n  ")
        UI.messagebox(error_msg)
      end
    end
    
    # 重新加载所有插件（简化版本）
    def self.reload_all_plugins
      begin
        puts "开始重新加载所有插件..."
        
        # 获取插件目录
        plugins_dir = Sketchup.find_support_file("Plugins")
        unless plugins_dir && Dir.exist?(plugins_dir)
          puts "插件目录不存在: #{plugins_dir}"
          return
        end
        
        puts "插件目录: #{plugins_dir}"
        
        # 重新加载所有.rb文件（只加载根目录的文件，避免递归问题）
        rb_files = Dir.glob(File.join(plugins_dir, "*.rb"))
        puts "找到 #{rb_files.length} 个插件文件"
        
        success_count = 0
        error_count = 0
        
        rb_files.each do |rb_file|
          begin
            # 跳过当前文件，避免递归加载
            next if File.basename(rb_file) == File.basename(__FILE__)
            
            # 跳过系统插件
            basename = File.basename(rb_file, '.rb')
            next if ['su_dynamiccomponents', 'su_sandbox', 'habitat_site_context'].include?(basename)
            
            puts "重新加载: #{File.basename(rb_file)}"
            
            # 清理$LOADED_FEATURES中的记录
            $LOADED_FEATURES.delete_if { |f| f.include?(rb_file) }
            
            # 重新加载文件
            load rb_file
            success_count += 1
            
          rescue => e
            error_count += 1
            puts "加载插件失败 #{File.basename(rb_file)}: #{e.message}"
          end
        end
        
        # 强制垃圾回收
        GC.start
        
        puts "插件重新加载完成: #{success_count} 成功, #{error_count} 失败"
        
      rescue => e
        puts "重新加载插件失败: #{e.message}"
        puts e.backtrace.join("\n  ")
      end
    end
    
    # 获取SketchUp可执行文件路径
    def self.get_sketchup_executable_path
      begin
        puts "开始查找SketchUp可执行文件路径..."
        
        # 方法1: 使用cmd命令查找当前运行的SketchUp进程（最可靠）
        cmd_path = get_sketchup_using_cmd
        return cmd_path if cmd_path && File.exist?(cmd_path)
        
        # 方法2: 通过Ruby获取当前SketchUp进程信息
        current_exe_path = get_current_sketchup_path
        return current_exe_path if current_exe_path && File.exist?(current_exe_path)
        
        puts "Ruby方法获取路径: #{current_exe_path || '失败'}"
        
        # 方法3: 尝试多种可能的路径
        possible_paths = [
          "C:\\Program Files\\SketchUp\\SketchUp 2024\\SketchUp.exe",
          "C:\\Program Files\\SketchUp\\SketchUp 2025\\SketchUp.exe",
          "C:\\Program Files (x86)\\SketchUp\\SketchUp 2024\\SketchUp.exe",
          "C:\\Program Files (x86)\\SketchUp\\SketchUp 2025\\SketchUp.exe"
        ]
        
        # 检查每个可能的路径
        possible_paths.each do |path|
          if File.exist?(path)
            puts "找到SketchUp路径: #{path}"
            return path
          end
        end
        puts "常见路径检查完毕，未找到"
        
        # 方法4: 尝试从注册表获取（Windows）
        registry_path = get_sketchup_from_registry
        return registry_path if registry_path && File.exist?(registry_path)
        
        # 方法5: 尝试通过环境变量查找
        env_path = get_sketchup_from_environment
        return env_path if env_path && File.exist?(env_path)
        
        # 方法6: 使用where命令查找
        where_path = get_sketchup_using_where
        return where_path if where_path && File.exist?(where_path)
        
        puts "所有方法都无法找到SketchUp可执行文件"
        return nil
        
      rescue => e
        puts "获取SketchUp路径时出错: #{e.message}"
        return nil
      end
    end
    
    # 通过Ruby获取当前SketchUp进程路径
    def self.get_current_sketchup_path
      begin
        # 尝试通过$0获取
        if $0 && !$0.empty?
          exe_path = File.expand_path($0)
          if exe_path.include?('SketchUp') && exe_path.end_with?('.exe')
            return exe_path
          end
        end
        
        # 尝试通过__FILE__推断
        current_file = __FILE__
        if current_file && current_file.include?('SketchUp')
          # 从插件路径推断SketchUp安装路径
          # 例如: C:\Users\...\SketchUp 2024\SketchUp\Plugins\xxx.rb
          # 推断为: C:\Program Files\SketchUp\SketchUp 2024\SketchUp.exe
          if current_file.match(/SketchUp\s+(\d{4})/)
            version = $1
            ['C:\\Program Files', 'C:\\Program Files (x86)'].each do |base|
              exe_path = File.join(base, 'SketchUp', "SketchUp #{version}", 'SketchUp.exe')
              return exe_path if File.exist?(exe_path)
            end
          end
        end
        
        return nil
      rescue
        return nil
      end
    end
    
    # 从注册表获取SketchUp路径
    def self.get_sketchup_from_registry
      begin
        require 'win32/registry'
        Win32::Registry::HKEY_LOCAL_MACHINE.open('SOFTWARE\\SketchUp') do |reg|
          reg.each_key do |key|
            if key.include?('2024') || key.include?('2025')
              reg.open(key) do |subkey|
                install_path = subkey['InstallLocation'] rescue nil
                if install_path && File.exist?(File.join(install_path, 'SketchUp.exe'))
                  exe_path = File.join(install_path, 'SketchUp.exe')
                  puts "注册表找到路径: #{exe_path}"
                  return exe_path
                end
              end
            end
          end
        end
      rescue => e
        puts "注册表查找失败: #{e.message}"
      end
      return nil
    end
    
    # 通过环境变量获取SketchUp路径
    def self.get_sketchup_from_environment
      begin
        program_files = ENV['ProgramFiles'] || 'C:\\Program Files'
        program_files_x86 = ENV['ProgramFiles(x86)'] || 'C:\\Program Files (x86)'
        
        [program_files, program_files_x86].each do |base_path|
          ['2024', '2025'].each do |version|
            exe_path = File.join(base_path, 'SketchUp', "SketchUp #{version}", 'SketchUp.exe')
            if File.exist?(exe_path)
              puts "环境变量找到路径: #{exe_path}"
              return exe_path
            end
          end
        end
      rescue => e
        puts "环境变量查找失败: #{e.message}"
      end
      return nil
    end
    
    # 使用where命令查找SketchUp
    def self.get_sketchup_using_where
      begin
        # 使用where命令查找SketchUp.exe
        result = `where SketchUp.exe 2>nul`.strip
        if !result.empty? && File.exist?(result)
          puts "where命令找到路径: #{result}"
          return result
        end
      rescue => e
        puts "where命令查找失败: #{e.message}"
      end
      return nil
    end
    
    # 使用cmd命令查找当前运行的SketchUp进程
    def self.get_sketchup_using_cmd
      begin
        puts "使用cmd命令查找SketchUp进程..."
        
        # 方法1: 使用tasklist查找SketchUp进程
        tasklist_result = `tasklist /FI "IMAGENAME eq SketchUp.exe" /FO CSV 2>nul`.strip
        puts "tasklist结果: #{tasklist_result}"
        
        if tasklist_result.include?('SketchUp.exe')
          # 解析CSV输出获取进程信息
          lines = tasklist_result.split("\n")
          if lines.length > 1
            # 跳过标题行，获取进程信息
            process_line = lines[1]
            puts "进程信息: #{process_line}"
          end
        end
        
        # 方法2: 使用wmic查找SketchUp进程的完整路径
        wmic_result = `wmic process where "name='SketchUp.exe'" get ExecutablePath /format:value 2>nul`.strip
        puts "wmic结果: #{wmic_result}"
        
        if wmic_result.include?('ExecutablePath=')
          # 解析wmic输出
          wmic_result.split("\n").each do |line|
            if line.start_with?('ExecutablePath=') && !line.end_with?('ExecutablePath=')
              exe_path = line.sub('ExecutablePath=', '').strip
              if !exe_path.empty? && File.exist?(exe_path)
                puts "wmic找到路径: #{exe_path}"
                return exe_path
              end
            end
          end
        end
        
        # 方法3: 使用PowerShell查找进程路径
        ps_result = `powershell "Get-Process -Name SketchUp -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Path" 2>nul`.strip
        puts "PowerShell结果: #{ps_result}"
        
        if !ps_result.empty? && File.exist?(ps_result)
          puts "PowerShell找到路径: #{ps_result}"
          return ps_result
        end
        
        # 方法4: 搜索所有驱动器的Program Files目录
        drives = get_available_drives
        puts "搜索驱动器: #{drives.join(', ')}"
        
        drives.each do |drive|
          ['Program Files', 'Program Files (x86)'].each do |pf|
            base_path = File.join(drive, pf, 'SketchUp')
            if Dir.exist?(base_path)
              puts "找到SketchUp目录: #{base_path}"
              Dir.glob(File.join(base_path, '*')).each do |version_dir|
                if Dir.exist?(version_dir)
                  exe_path = File.join(version_dir, 'SketchUp.exe')
                  if File.exist?(exe_path)
                    puts "驱动器搜索找到路径: #{exe_path}"
                    return exe_path
                  end
                end
              end
            end
          end
        end
        
      rescue => e
        puts "cmd命令查找失败: #{e.message}"
        puts e.backtrace.join("\n  ")
      end
      return nil
    end
    
    # 获取可用的驱动器列表
    def self.get_available_drives
      begin
        drives_result = `wmic logicaldisk get size,freespace,caption /format:value 2>nul`.strip
        drives = []
        current_drive = {}
        
        drives_result.split("\n").each do |line|
          line = line.strip
          if line.start_with?('Caption=')
            current_drive[:caption] = line.sub('Caption=', '')
          elsif line.start_with?('Size=')
            current_drive[:size] = line.sub('Size=', '')
          elsif line.start_with?('FreeSpace=')
            current_drive[:freespace] = line.sub('FreeSpace=', '')
            # 当收集完一个驱动器的信息后，添加到列表
            if current_drive[:caption] && !current_drive[:caption].empty? && current_drive[:size] && !current_drive[:size].empty?
              drives << current_drive[:caption]
            end
            current_drive = {}
          end
        end
        
        # 如果上面的方法失败，使用简单的方法
        if drives.empty?
          ('A'..'Z').each do |letter|
            drive = "#{letter}:"
            if Dir.exist?(drive)
              drives << drive
            end
          end
        end
        
        return drives.empty? ? ['C:'] : drives
      rescue
        return ['C:', 'D:', 'E:']
      end
    end
    
    # 创建重启脚本
    def self.create_restart_script(sketchup_exe, model_path = nil)
      begin
        # 创建临时批处理文件
        temp_dir = ENV['TEMP'] || ENV['TMP'] || 'C:\\temp'
        script_path = File.join(temp_dir, 'sketchup_restart.bat')
        
        # 生成批处理脚本内容
        script_content = <<~BATCH
          @echo off
          echo 正在重启 SketchUp...
          
          REM 等待当前SketchUp进程完全关闭
          timeout /t 3 /nobreak >nul
          
          REM 确保SketchUp进程已关闭
          taskkill /f /im SketchUp.exe >nul 2>&1
          
          REM 再等待一秒
          timeout /t 1 /nobreak >nul
          
          REM 启动新的SketchUp实例
        BATCH
        
        if model_path && !model_path.empty? && File.exist?(model_path)
          script_content += "          start \"\" \"#{sketchup_exe}\" \"#{model_path}\"\n"
        else
          script_content += "          start \"\" \"#{sketchup_exe}\"\n"
        end
        
        script_content += <<~BATCH
          
          REM 等待SketchUp启动
          timeout /t 2 /nobreak >nul
          
          REM 删除此脚本文件
          del "%~f0"
        BATCH
        
        # 写入脚本文件
        File.write(script_path, script_content, encoding: 'UTF-8')
        
        return script_path
      rescue => e
        puts "创建重启脚本失败: #{e.message}"
        return nil
      end
    end
    
  end
end